package com.jcark.ui.view.textview;

import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.util.AttributeSet;

import androidx.appcompat.widget.AppCompatTextView;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;

/**
 * 可滚动数字的textview
 */
public class RiseNumberTextView extends AppCompatTextView implements IRiseNumber {
    private static final int STOPPED = 0;

    private static final int RUNNING = 1;

    private int mPlayingState = STOPPED;

    private double number;

    private float fromNumber;

    private long duration = 500;
    /**
     * 1.int 2.float
     */
    private int numberType = 2;

    private boolean flags = true;

    private EndListener mEndListener = null;

    private DecimalFormat mDecimalFormat = null;

    final static int[] sSizeTable = {9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, Integer.MAX_VALUE};

    public RiseNumberTextView(Context context) {
        super(context);
    }

    public RiseNumberTextView(Context context, AttributeSet attr) {
        super(context, attr);
    }

    public RiseNumberTextView(Context context, AttributeSet attr, int defStyle) {
        super(context, attr, defStyle);
    }

    public interface EndListener {
        void onEndFinish();
    }

    public boolean isRunning() {
        return (mPlayingState == RUNNING);
    }

    private void runFloat() {
        ValueAnimator valueAnimator = ValueAnimator.ofObject(new BigDecimalEvaluator(),
                new Object[]{new BigDecimal(0), new BigDecimal(this.number)});
        valueAnimator.setDuration(duration);

        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                setText(decimalFormat(",##0.00").format(Double.parseDouble(valueAnimator.getAnimatedValue().toString())));

//                if (flags) {
//                    //,##增加数字千分符
////                    setText(DoubleUtils.format(",##0.00").format(number));
//                    setText(DoubleUtils.format(",##0.00").format(Double.parseDouble(valueAnimator.getAnimatedValue
//                    ().toString())));
//
//                    if (valueAnimator.getAnimatedValue().toString().equalsIgnoreCase(number + "")) {
//                        setText(DoubleUtils.format(",##0.00").format(Double.parseDouble(number + "")));
//                    }
//                } else {
////                    setText(DoubleUtils.format(",##0.00").format(number));
//                    setText(DoubleUtils.format(",##0.00").format(Double.parseDouble(valueAnimator.getAnimatedValue
//                    ().toString())));
//                    if (valueAnimator.getAnimatedValue().toString().equalsIgnoreCase(number + "")) {
//                        setText(DoubleUtils.format(",##0.00").format(Double.parseDouble(number + "")));
//                    }
//                }
                if (valueAnimator.getAnimatedFraction() >= 1) {
                    mPlayingState = STOPPED;
                    if (mEndListener != null) {
                        mEndListener.onEndFinish();
                    }
                }
            }
        });
        valueAnimator.start();
    }

    private DecimalFormat decimalFormat(String pattern) {
        if (mDecimalFormat == null) {
            mDecimalFormat = new DecimalFormat();
        }
        mDecimalFormat.setRoundingMode(RoundingMode.HALF_UP);
        mDecimalFormat.applyPattern(pattern);
        return mDecimalFormat;
    }

    private void runInt() {
        ValueAnimator valueAnimator = ValueAnimator.ofInt((int) fromNumber, (int) number);
        valueAnimator.setDuration(duration);

        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {

                setText(valueAnimator.getAnimatedValue().toString());
                if (valueAnimator.getAnimatedFraction() >= 1) {
                    mPlayingState = STOPPED;
                    if (mEndListener != null) {
                        mEndListener.onEndFinish();
                    }
                }
            }
        });
        valueAnimator.start();
    }

    static int sizeOfInt(int x) {
        for (int i = 0; ; i++) {
            if (x <= sSizeTable[i]) {
                return i + 1;
            }
        }
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
    }

    @Override
    public void start() {

        if (!isRunning()) {
            mPlayingState = RUNNING;
            if (numberType == 1) {
                runInt();
            } else {
                runFloat();
            }
        }
    }

    @Override
    public RiseNumberTextView withNumber(float number, boolean flag) {

        this.number = number;
        this.flags = flag;
        numberType = 2;
        fromNumber = 0;

        return this;
    }

    @Override
    public RiseNumberTextView withNumber(double number) {
        System.out.println(number);
        this.number = number;
        numberType = 2;
        fromNumber = 0;

        return this;
    }

    @Override
    public RiseNumberTextView withNumber(int number) {
        this.number = number;
        numberType = 1;
        fromNumber = 0;

        return this;
    }

    @Override
    public RiseNumberTextView setDuration(long duration) {
        this.duration = duration;
        return this;
    }

    @Override
    public void setOnEnd(EndListener callback) {
        mEndListener = callback;
    }

    static class BigDecimalEvaluator implements TypeEvaluator {
        BigDecimalEvaluator() {
        }

        @Override
        public Object evaluate(float fraction, Object startValue, Object endValue) {
            BigDecimal start = (BigDecimal) startValue;
            BigDecimal end = (BigDecimal) endValue;
            BigDecimal result = end.subtract(start);
            return result.multiply(new BigDecimal("" + fraction)).add(start);
        }
    }
}

